import React, { memo, useState, useEffect } from 'react';
import { Result, Button, Typography, Space, Progress } from 'antd';
import { 
  WifiOutlined,
  ReloadOutlined,
  ExclamationCircleOutlined,
  CheckCircleOutlined,
  LoadingOutlined
} from '@ant-design/icons';
import classNames from 'classnames';
import styles from './NetworkError.module.css';

const { Text, Paragraph } = Typography;

/**
 * 网络状态枚举
 */
export enum NetworkStatus {
  /** 在线 */
  ONLINE = 'online',
  /** 离线 */
  OFFLINE = 'offline',
  /** 连接中 */
  CONNECTING = 'connecting',
  /** 连接失败 */
  FAILED = 'failed'
}

/**
 * 网络错误类型枚举
 */
export enum NetworkErrorType {
  /** 连接超时 */
  TIMEOUT = 'timeout',
  /** 连接被拒绝 */
  CONNECTION_REFUSED = 'connection_refused',
  /** DNS解析失败 */
  DNS_ERROR = 'dns_error',
  /** 服务器不可达 */
  SERVER_UNREACHABLE = 'server_unreachable',
  /** 网络不可用 */
  NETWORK_UNAVAILABLE = 'network_unavailable',
  /** 未知网络错误 */
  UNKNOWN = 'unknown'
}

/**
 * 网络错误组件属性接口
 */
export interface INetworkErrorProps {
  /** 网络状态 */
  status?: NetworkStatus;
  /** 错误类型 */
  errorType?: NetworkErrorType;
  /** 自定义错误消息 */
  message?: string;
  /** 自定义错误描述 */
  description?: string;
  /** 是否显示重试按钮 */
  showRetryButton?: boolean;
  /** 重试按钮文本 */
  retryButtonText?: string;
  /** 重试回调函数 */
  onRetry?: () => void | Promise<void>;
  /** 是否自动重试 */
  autoRetry?: boolean;
  /** 自动重试间隔（秒） */
  retryInterval?: number;
  /** 最大重试次数 */
  maxRetryCount?: number;
  /** 是否显示网络状态检测 */
  showNetworkDetection?: boolean;
  /** 是否显示进度条 */
  showProgress?: boolean;
  /** 自定义类名 */
  className?: string;
  /** 自定义样式 */
  style?: React.CSSProperties;
}

/**
 * 网络错误处理组件
 * @description 处理各种网络错误情况，提供重试和状态检测功能
 */
const NetworkError = memo<INetworkErrorProps>(({
  status = NetworkStatus.OFFLINE,
  errorType = NetworkErrorType.UNKNOWN,
  message,
  description,
  showRetryButton = true,
  retryButtonText = '重新连接',
  onRetry,
  autoRetry = false,
  retryInterval = 5,
  maxRetryCount = 3,
  showNetworkDetection = true,
  showProgress = false,
  className,
  style
}) => {
  const [currentStatus, setCurrentStatus] = useState<NetworkStatus>(status);
  const [retryCount, setRetryCount] = useState(0);
  const [isRetrying, setIsRetrying] = useState(false);
  const [countdown, setCountdown] = useState(0);
  const [networkOnline, setNetworkOnline] = useState(navigator.onLine);

  // 监听网络状态变化
  useEffect(() => {
    const handleOnline = () => {
      setNetworkOnline(true);
      setCurrentStatus(NetworkStatus.ONLINE);
    };

    const handleOffline = () => {
      setNetworkOnline(false);
      setCurrentStatus(NetworkStatus.OFFLINE);
    };

    window.addEventListener('online', handleOnline);
    window.addEventListener('offline', handleOffline);

    return () => {
      window.removeEventListener('online', handleOnline);
      window.removeEventListener('offline', handleOffline);
    };
  }, []);

  // 自动重试逻辑
  useEffect(() => {
    let timer: number;
    let countdownTimer: number;

    if (autoRetry && currentStatus === NetworkStatus.FAILED && retryCount < maxRetryCount) {
      setCountdown(retryInterval);
      
      countdownTimer = window.setInterval(() => {
        setCountdown(prev => {
          if (prev <= 1) {
            window.clearInterval(countdownTimer);
            return 0;
          }
          return prev - 1;
        });
      }, 1000);

      timer = window.setTimeout(() => {
        handleRetry();
      }, retryInterval * 1000);
    }

    return () => {
      if (timer) window.clearTimeout(timer);
      if (countdownTimer) window.clearInterval(countdownTimer);
    };
  }, [autoRetry, currentStatus, retryCount, maxRetryCount, retryInterval]);

  // 处理重试
  const handleRetry = async () => {
    if (isRetrying) return;

    setIsRetrying(true);
    setCurrentStatus(NetworkStatus.CONNECTING);
    setRetryCount(prev => prev + 1);

    try {
      if (onRetry) {
        await onRetry();
        setCurrentStatus(NetworkStatus.ONLINE);
        setRetryCount(0);
      } else {
        // 默认重试逻辑：检查网络连接
        await checkNetworkConnection();
      }
    } catch (error) {
      setCurrentStatus(NetworkStatus.FAILED);
    } finally {
      setIsRetrying(false);
    }
  };

  // 检查网络连接
  const checkNetworkConnection = async (): Promise<void> => {
    return new Promise((resolve, reject) => {
      // 尝试加载一个小的图片来检测网络连接
      const img = new Image();
      const timeout = window.setTimeout(() => {
        reject(new Error('Connection timeout'));
      }, 5000);

      img.onload = () => {
        window.clearTimeout(timeout);
        setCurrentStatus(NetworkStatus.ONLINE);
        resolve();
      };

      img.onerror = () => {
        window.clearTimeout(timeout);
        reject(new Error('Connection failed'));
      };

      // 使用一个小的图片URL进行测试
      img.src = `?t=${Date.now()}`;
    });
  };

  // 获取错误信息
  const getErrorInfo = () => {
    if (message && description) {
      return { title: message, desc: description };
    }

    switch (errorType) {
      case NetworkErrorType.TIMEOUT:
        return {
          title: '连接超时',
          desc: '网络连接超时，请检查网络设置后重试'
        };
      case NetworkErrorType.CONNECTION_REFUSED:
        return {
          title: '连接被拒绝',
          desc: '服务器拒绝了连接请求，请稍后重试'
        };
      case NetworkErrorType.DNS_ERROR:
        return {
          title: 'DNS解析失败',
          desc: '无法解析服务器地址，请检查网络设置'
        };
      case NetworkErrorType.SERVER_UNREACHABLE:
        return {
          title: '服务器不可达',
          desc: '无法连接到服务器，请检查网络连接'
        };
      case NetworkErrorType.NETWORK_UNAVAILABLE:
        return {
          title: '网络不可用',
          desc: '当前网络不可用，请检查网络连接'
        };
      default:
        return {
          title: '网络连接失败',
          desc: '网络连接出现问题，请检查网络设置后重试'
        };
    }
  };

  // 获取状态图标
  const getStatusIcon = () => {
    switch (currentStatus) {
      case NetworkStatus.ONLINE:
        return <CheckCircleOutlined style={{ color: '#52c41a', fontSize: 64 }} />;
      case NetworkStatus.CONNECTING:
        return <LoadingOutlined style={{ color: '#1890ff', fontSize: 64 }} />;
      case NetworkStatus.FAILED:
      case NetworkStatus.OFFLINE:
      default:
        return <WifiOutlined style={{ color: '#ff4d4f', fontSize: 64 }} />;
    }
  };

  // 获取状态文本
  const getStatusText = () => {
    switch (currentStatus) {
      case NetworkStatus.ONLINE:
        return '网络连接正常';
      case NetworkStatus.CONNECTING:
        return '正在连接...';
      case NetworkStatus.FAILED:
        return '连接失败';
      case NetworkStatus.OFFLINE:
      default:
        return '网络连接断开';
    }
  };

  // 渲染网络检测信息
  const renderNetworkDetection = () => {
    if (!showNetworkDetection) return null;

    return (
      <div className={styles.networkDetection}>
        <Space direction="vertical" size="small" align="center">
          <Text type="secondary">网络状态检测</Text>
          <Space>
            <Text>浏览器网络状态:</Text>
            <Text type={networkOnline ? 'success' : 'danger'}>
              {networkOnline ? '在线' : '离线'}
            </Text>
          </Space>
          <Space>
            <Text>服务器连接状态:</Text>
            <Text type={currentStatus === NetworkStatus.ONLINE ? 'success' : 'danger'}>
              {getStatusText()}
            </Text>
          </Space>
        </Space>
      </div>
    );
  };

  // 渲染重试信息
  const renderRetryInfo = () => {
    if (!autoRetry || currentStatus !== NetworkStatus.FAILED) return null;

    if (retryCount >= maxRetryCount) {
      return (
        <div className={styles.retryInfo}>
          <Text type="secondary">
            已达到最大重试次数 ({maxRetryCount})，请手动重试
          </Text>
        </div>
      );
    }

    if (countdown > 0) {
      return (
        <div className={styles.retryInfo}>
          <Space direction="vertical" size="small" align="center">
            <Text type="secondary">
              {countdown} 秒后自动重试 (第 {retryCount + 1} 次)
            </Text>
            {showProgress && (
              <Progress
                percent={((retryInterval - countdown) / retryInterval) * 100}
                size="small"
                showInfo={false}
                strokeColor="#1890ff"
              />
            )}
          </Space>
        </div>
      );
    }

    return null;
  };

  // 渲染操作按钮
  const renderActions = () => {
    const actions = [];

    if (showRetryButton) {
      actions.push(
        <Button
          key="retry"
          type="primary"
          icon={<ReloadOutlined />}
          loading={isRetrying}
          onClick={handleRetry}
          disabled={currentStatus === NetworkStatus.ONLINE}
        >
          {isRetrying ? '连接中...' : retryButtonText}
        </Button>
      );
    }

    return actions;
  };

  const errorInfo = getErrorInfo();

  // 组合类名
  const networkErrorClassName = classNames(
    styles.networkError,
    {
      [styles.online]: currentStatus === NetworkStatus.ONLINE,
      [styles.connecting]: currentStatus === NetworkStatus.CONNECTING,
      [styles.failed]: currentStatus === NetworkStatus.FAILED,
      [styles.offline]: currentStatus === NetworkStatus.OFFLINE,
    },
    className
  );

  return (
    <div className={networkErrorClassName} style={style}>
      <Result
        icon={getStatusIcon()}
        title={errorInfo.title}
        subTitle={errorInfo.desc}
        extra={renderActions()}
      />
      
      {renderNetworkDetection()}
      {renderRetryInfo()}
    </div>
  );
});

NetworkError.displayName = 'NetworkError';

export default NetworkError;